/**
 * 代理Object
 */
function proxyObject(vm, data) {
    // 创建代理对象
    let proxyObj = {}
    for(let key in data) {
        Object.defineProperty(proxyObj, key, {
            get() {
                return data[key]
            },
            set(newValue) {
                console.log(`正在修改：${key} 值为：${data[key]}`)
                data[key] = newValue
            }
        })
        // 为MiniVue的根实例添加属性
        Object.defineProperty(vm, key, {
            get() {
                return data[key]
            },
            set(newValue) {
                console.log(`正在修改根：${key} 值为：${data[key]}`)
                data[key] = newValue
            }
        })
    }
    return proxyObj
}
/**
 * 代理Array数据
 * @param {*} vm 
 * @param {*} data 
 */
function proxyArray(vm, array) {
   // 创建代理对象
   let proxyObj = new Array(data.length);
   // 给数组的每一个元素都创建代理
   array.forEach((item, index) => {
        proxyObj[index] = constructProxy(item);
   })
   // 代理数组的方法
   proxyObj = defineArrayProto(array);
   return proxyObj;
}

 
/**
 * 代理Array方法
 * @param {*} array 
 * @param {*} namespace 
 * @returns 
 */
function defineArrayProto(array = [], namespace) {
    // 创建代理对象
    const obj = {
        type: 'Array',
        toString() {
            let result = "";
            for (let i = 0 ; i < array.length ; i ++) {
                result += array[i] + ", "
            }
            return result.substring(0, result.length - 2);
        },
		// 有功夫在重写一下
        push() {},
        pop() {},
        shift() {},
        unshift() {}
    }
    // 代理对象中的方法
    defineProxyMethod.call(vm, obj, 'push', namespace)
    defineProxyMethod.call(vm, obj, 'pop', namespace)
    defineProxyMethod.call(vm, obj, 'shift', namespace)
    defineProxyMethod.call(vm, obj, 'unshift', namespace)
    // 将原数组的隐式原型设置为代理对象
    array.__proto__ = obj
    return array
}


/**
 * 构建数据代理对象
 * @param {Object} vm
 * @param {Object} data
 * @param {Object} namespace
 */
export function constructProxy(vm, data, namespace) {
   let proxyObj = {};
   // 我们需要判断data的类型
   if(data instanceof Array) { // 需要先判断Array类型
		proxyObj = proxyArray(vm, data);
   } else if (data instanceof Object) { // 判断Object类型
      proxyObj = proxyObject(vm, data);
   } else {
      throw new Error('data must be an object or array');
   }
   return proxyObj;
}
